package cache

import (
	"bytes"
	"encoding/json"
	"strconv"
	"strings"
	"time"
)

// ----------------------------------------
//  Redis 字符串
// ----------------------------------------
type RedisString string

func (s RedisString) String() string {
	return string(s)
}

func (s RedisString) Buffer() *bytes.Buffer {
	return bytes.NewBufferString(s.String())
}

func (s RedisString) Bytes() []byte {
	return s.Buffer().Bytes()
}

func (s RedisString) IsEmpty() bool {
	return s == ""
}

func (s RedisString) TryBool() (bool, error) {
	if str := s.String(); s == "" {
		return false, nil
	} else {
		return strconv.ParseBool(str)
	}
}

func (s RedisString) Bool() bool {
	v, _ := s.TryBool()
	return v
}

func (s RedisString) TryFloat64() (float64, error) {
	return strconv.ParseFloat(s.String(), 0)
}

func (s RedisString) Float64() float64 {
	v, _ := s.TryFloat64()
	return v
}

func (s RedisString) TryFloat32() (float32, error) {
	v, err := s.TryFloat64()
	return float32(v), err
}

func (s RedisString) Float32() float32 {
	return float32(s.Float64())
}

func (s RedisString) TryInt64() (int64, error) {
	return strconv.ParseInt(s.String(), 10, 0)
}

func (s RedisString) Int64() int64 {
	v, _ := s.TryInt64()
	return v
}

func (s RedisString) TryInt() (int, error) {
	return strconv.Atoi(s.String())
}

func (s RedisString) Int() int {
	v, _ := s.TryInt()
	return v
}

func (s RedisString) TryInt32() (int32, error) {
	if v, err := strconv.ParseInt(s.String(), 10, 0); err == nil {
		return int32(v), nil
	} else {
		return 0, err
	}
}

func (s RedisString) Int32() int32 {
	v, _ := s.TryInt32()
	return v
}

func (s RedisString) TryInt16() (int16, error) {
	if v, err := strconv.ParseInt(s.String(), 10, 0); err == nil {
		return int16(v), nil
	} else {
		return 0, err
	}
}

func (s RedisString) Int16() int16 {
	v, _ := s.TryInt16()
	return v
}

func (s RedisString) TryInt8() (int8, error) {
	if v, err := strconv.ParseInt(s.String(), 10, 0); err == nil {
		return int8(v), nil
	} else {
		return 0, err
	}
}

func (s RedisString) Int8() int8 {
	v, _ := s.TryInt8()
	return v
}

func (s RedisString) TryUint64() (uint64, error) {
	return strconv.ParseUint(s.String(), 10, 0)
}

func (s RedisString) Uint64() uint64 {
	v, _ := s.TryUint64()
	return v
}

func (s RedisString) TryUint() (uint, error) {
	if v, err := strconv.ParseUint(s.String(), 10, 0); err == nil {
		return uint(v), nil
	} else {
		return 0, err
	}
}

func (s RedisString) Uint() uint {
	v, _ := s.TryUint()
	return v
}

func (s RedisString) TryUint32() (uint32, error) {
	if v, err := strconv.ParseUint(s.String(), 10, 0); err == nil {
		return uint32(v), nil
	} else {
		return 0, err
	}
}

func (s RedisString) Uint32() uint32 {
	v, _ := s.TryUint32()
	return v
}

func (s RedisString) TryUint16() (uint16, error) {
	if v, err := strconv.ParseUint(s.String(), 10, 0); err == nil {
		return uint16(v), nil
	} else {
		return 0, err
	}
}

func (s RedisString) Uint16() uint16 {
	v, _ := s.TryUint16()
	return v
}

func (s RedisString) TryUint8() (uint8, error) {
	if v, err := strconv.ParseUint(s.String(), 10, 0); err == nil {
		return uint8(v), nil
	} else {
		return 0, err
	}
}

func (s RedisString) Uint8() uint8 {
	v, _ := s.TryUint8()
	return v
}

func (s RedisString) TryParseTime(layout string) (time.Time, error) {
	return time.ParseInLocation(layout, s.String(), time.Local)
}

func (s RedisString) ParseTime(layout string) time.Time {
	t, _ := s.TryParseTime(layout)
	return t
}

func (s RedisString) TryTime() (time.Time, error) {
	return time.ParseInLocation("2006-01-02 15:04:05", s.String(), time.Local)
}

func (s RedisString) Time() time.Time {
	t, _ := s.TryTime()
	return t
}

func (s RedisString) JSON(v interface{}) error {
	return json.Unmarshal(s.Bytes(), v)
}

func (s RedisString) Slice(sep string) []string {
	if str := s.String(); str == "" {
		return nil
	} else {
		return strings.Split(str, sep)
	}
}
